var $ = layui.$;
var editor;
var flows;
var codeMirrorInstances = {};
var socket;
var version = 'lastest';
function renderCodeMirror(){
	codeMirrorInstances = {};
	$('[codemirror]').each(function(){
		var $dom = $(this);
		if($dom.attr("rendered") == 'true'){
			return;
		}
		$dom.attr("rendered",true)
		var cm = CodeMirror(this,{
			mode : 'spiderflow',	//语法
			theme : 'idea',	//设置样式
			placeholder : $dom.attr("placeholder"),
			value : $dom.attr('data-value') || '',
			scrollbarStyle : 'null',	//隐藏滚动条
		});
		initHint(cm);
		codeMirrorInstances[$(this).attr('codemirror')] = cm;
		cm.on('change',function(){
			$dom.attr('data-value',cm.getValue());
			if($dom.attr('codemirror') == 'condition'){
				var $select = $('select[name="exception-flow"]');
				$select.siblings("div.layui-form-select").find('dl dd[lay-value=' + $select.val() + ']').click();
			}
			serializeForm();
		});
		codeMirrorInstances[$(this).attr('codemirror')] = cm;
	});
}
function getCellData(cellId,keys){
	var cell = editor.getModel().getCell(cellId);
	var data = [];
	var object = cell.data.object;
	for(var k in keys){
		var key = keys[k];
		if(Array.isArray(object[key])){
			var array = object[key];
			for(var i =0,len = array.length;i<len;i++){
				data[i] = data[i] || {};
				data[i][key] = array[i];
			}
		}
	}
	return data;
}
function serializeForm(){
	var $container = $(".properties-container");
	var _version = $container.data('version');
	if(_version && _version != version){
		return;
	}
	var cellId = $container.attr('data-cellid');
	var model = editor.getModel();
	var cell = model.getCell(cellId);
	if(!cell){
		return;
	}
	var shape = cell.data.get('shape');
	cell.data.reset({});
	$.each($(".properties-container form").serializeArray(),function(index,item){
		var name = item.name;
		var value = item.value;
		if($(".properties-container form *[name="+name+"].array").length > 0){
			var array = cell.data.get(name) || [];
			array.push(value);
			cell.data.set(name,array);
		}else{
			if(name == 'value'){
				if(cell.getValue() != value){
					model.beginUpdate();
					try{
						cell.setValue(value);
						model.execute(new mxValueChange(model,cell,value));
					}finally{
						model.endUpdate();
					}
				}
			}
			if(name == 'lineWidth'){
				editor.graph.setCellStyles('strokeWidth',value,[cell]);
			}
			if(name == 'line-style'){
				editor.graph.setCellStyles('sharp',undefined,[cell]);
				editor.graph.setCellStyles('rounded',undefined,[cell]);
				editor.graph.setCellStyles('curved',undefined,[cell]);
				editor.graph.setCellStyles(value,1,[cell]);
			}
			cell.data.set(name,value);
		}
	});
	$(".properties-container form [codemirror]").each(function(){
		var $dom = $(this);
		var name = $dom.attr('codemirror');
		var value = $dom.attr('data-value');
		if($dom.hasClass("array")){
			var array = cell.data.get(name) || [];
			array.push(value);
			cell.data.set(name,array);
		}else{
			cell.data.set(name,value);
		}
	});
	$(".properties-container form input[type=checkbox]").each(function(){
		if(this.value == 'transmit-variable'){
			if($(this).is(":checked")){
				editor.graph.setCellStyles('dashed',undefined,[cell]);
			}else{
				editor.graph.setCellStyles('dashed',1,[cell]);
			}
		}
		cell.data.set(this.value,$(this).is(":checked") ? '1': '0');
	});
	cell.data.set('shape',shape);
}
function resizeSlideBar(){
	var $dom = $(".sidebar-container");
	var height = $dom.height();
	var len = $dom.find("img").length;
	var totalHeight = len * 46;
	var w = Math.ceil(totalHeight / height);
	$dom.width(w * 50);
	$(".editor-container,.xml-container").css("left",w * 50 + "px");
}

function validXML(callback){
	var cell = editor.valid();
	if(cell){
		layui.layer.confirm("检测到有箭头未连接到节点上，是否处理？",{
			title : '异常处理',
			btn : ['处理','忽略'],
		},function(index){
			layui.layer.close(index);
			editor.selectCell(cell);
		},function(){
			callback&&callback();
		})
	}else{
		callback&&callback();
	}
}
$(function(){
	$.ajax({
		url : 'spider/other',
		type : 'post',
		data : {
			id : getQueryString('id')
		},
		dataType : 'json',
		success : function(others){
			flows = others;
		}
	})
	$.ctrl = function(key, callback, args) {
	    var isCtrl = false;
	    $(document).keydown(function(e) {
	        if(!args) args=[];
	        if(e.keyCode == 17) isCtrl = true;
	        if(e.keyCode == key.charCodeAt(0) && isCtrl) {
	            callback.apply(this, args);
	            isCtrl = false;
	            return false;
	        }
	    }).keyup(function(e) {
	        if(e.keyCode == 17) isCtrl = false;
	    });        
	};
	$.ctrl('S', function() {
		$('input,textarea').blur();
		Save();
	});
	$.ctrl('Q', function() {
		$('input,textarea').blur();
		$(".btn-test").click();
	});
	resizeSlideBar();
	var templateCache = {};
	function loadTemplate(cell,model,callback){
		serializeForm();
		var cells = model.cells;
		var template = cell.data.get('shape') || 'root';
		if(cell.isEdge()){
			template = 'edge';
		}
		var v = version;
		var render = function(){
			layui.laytpl(templateCache[template]).render({
				data : cell.data,
				value : cell.value,
				flows : flows || [],
				model : model,
				cell : cell
			},function(html){
				$(".properties-container").attr('data-version',v).html(html).attr('data-cellid',cell.id);
				layui.form.render();
				renderCodeMirror();
				resizeSlideBar();
				callback&&callback();
			})
		}
		if(templateCache[template]){
			render();
			return;
		}
		$.ajax({
			url : 'resources/templates/' + template +".html",
			async :false,
			success : function(content){
				templateCache[template] = content;
				render();
			}
		});
	}
	if (!mxClient.isBrowserSupported()){
		layui.layer.msg('浏览器不支持!!');
	}else{
		editor = new SpiderEditor({
			element : $('.editor-container')[0],
			selectedCellListener : function(cell){	//选中节点后打开属性面板
				loadTemplate(cell,editor.getModel(),serializeForm);
			}
		});
		//绑定工具条点击事件
		bindToolbarClickAction(editor);
		//加载图形
		loadShapes(editor,$('.sidebar-container')[0]);
		layui.form.on('checkbox',function(e){
			serializeForm();
		});
		layui.table.on('tool',function(obj){
			layui.layer.confirm('您确定要删除吗？',{
				title : '删除'
			},function(index) {
				obj.del();
				serializeForm();
				renderCodeMirror();
				layui.layer.close(index);
			});
		})
		//节点名称输入框事件
		$("body").on("mousewheel",".layui-tab .layui-tab-title",function(e,delta){
			var $dom = $(this);
			var wheel = e.originalEvent.wheelDelta || -e.originalEvent.detail;
		    var delta = Math.max(-1, Math.min(1, wheel) );
		    e.preventDefault = function(){}
		    if(delta > 0){
		        $dom.scrollLeft($dom.scrollLeft()-60);
			}else{
				$dom.scrollLeft($dom.scrollLeft()+60);
			}
			return false;
		}).on("dblclick",".layui-input-block[codemirror]",function(){
			if($(this).parent().hasClass("layui-layer-content")){
				return;
			}
			layui.layer.open({
				type : 1,
				title : '请输入'+$(this).prev().html()+'表达式',
				content : $(this),
				skin : 'codemirror',
				area : '800px'
			})
		}).on("blur","input,textarea",function(){
			serializeForm();
		}).on("click",".history-version li",function(){
			var timestamp = $(this).data("timestamp");
			layui.layer.confirm('你确定要恢复到该版本吗？',function(index){
				layui.layer.close(index);
				var layerIndex = layui.layer.load(1);
				$.ajax({
					url : 'spider/history',
					data : {
						id : id,
						timestamp : timestamp
					},
					success : function(data){
						if(data.code == 1){
							version = timestamp;
							editor.setXML(data.data);
							layui.layer.close(layerIndex);
							layui.layer.msg('恢复成功')
						}else{
							layui.layer.msg(data.message);
						}
					}
				})
			});
		}).on("click",".btn-history",function(){
			$.ajax({
				url : 'spider/history',
				data : {
					id : id
				},
				success : function(data){
					if(data.code == 1){
						if(data.data.length > 0){
							var array = [];
							for(var i = data.data.length - 1;i >=0;i--){
								var timestamp = Number(data.data[i])
								array.push({
									time : new Date(timestamp).format('yyyy-MM-dd hh:mm:ss'),
									timestamp : timestamp
								})
							}
							layui.laytpl($('#history-version-tmpl').html()).render(array,function(html){
								layui.layer.open({
									type : 1,
									title : '历史版本',
									id : 'history-revert',
									shade : 0,
									resize : false,
									content : html,
									offset : 'rt'
								})
							})
						}else{
							layui.layer.msg('暂无历史版本！');
						}
					}else{
						layui.layer.msg(data.message);
					}
				}
			})
		}).on("click",".table-row-add",function(){	//添加一行
			serializeForm();
			var tableId = $(this).attr('for');
			var $table = $('#' + tableId);
			var cellId = $table.data('cell');
			var data = getCellData(cellId,$table.data('keys').split(","));
			data.push({});
			layui.table.reload(tableId,{
				data : data
			});
			renderCodeMirror();
		}).on("click",".table-row-up",function(){	//上移
			var current = $(this).parent().parent().parent(); //获取当前<tr>
			var prev = current.prev();  //获取当前<tr>前一个元素
			if (current.index() > 0) {
				current.insertBefore(prev); //插入到当前<tr>前一个元素前
				serializeForm();
			}
			renderCodeMirror();
		}).on("click",".table-row-down",function(){	//下移
			var current = $(this).parent().parent().parent(); //获取当前<tr>
			var next = current.next(); //获取当前<tr>后面一个元素
			if (next) {
				current.insertAfter(next);  //插入到当前<tr>后面一个元素后面
				serializeForm();
			}
			renderCodeMirror();
		}).on("click",".editor-form-node .function-remove,.editor-form-node .cmd-remove",function () {
			var $dom = $(this).parents(".draggable");
			$dom.remove();
			serializeForm();
		}).on("click",".editor-form-node .cookie-batch",function(){
			var tableId = $(this).attr('for');
			var $table = $('#' + tableId);
			var cellId = $table.data('cell');
			var data = getCellData(cellId,$table.data('keys').split(","));
			layui.layer.open({
				type : 1,
				title : '请输入Cookie',
				content : `<textarea id="cookies" name="cookies" placeholder="请输入Cookies，分号( ; )分隔Cookie，等于号( = )分隔name和value" autocomplete="off" class="layui-textarea"  lay-verify="required" style="height:250px"></textarea>`,
				area : '800px',
				btn : ['关闭','设置'],
				btn2 : function(){
					var cookieStr = $("#cookies").val();
					var cookieArr = cookieStr.split(";");
					var length = $(".draggable").length;
					serializeForm();
					for (var i = 0; i < cookieArr.length; i++) {
						var cookieItem = cookieArr[i];
						var index = cookieItem.indexOf("=");
						if (index < 0) {
							layer.alert('cookie数据格式错误');
							appendFlag = false;
							return;
						} else {
							data.push({
								'cookie-name' : $.trim(cookieItem.substring(0, index)),
								'cookie-value' : $.trim(cookieItem.substring(index + 1))
							})
						}
					}
					layui.table.reload(tableId,{
						data : data
					});
					renderCodeMirror();
					serializeForm();
				}
			})
		}).on("click",".editor-form-node .header-batch",function(){
			var tableId = $(this).attr('for');
			var $table = $('#' + tableId);
			var cellId = $table.data('cell');
			var data = getCellData(cellId,$table.data('keys').split(","));
			layui.layer.open({
				type : 1,
				title : '请输入Header',
				content : `<textarea id="headers" name="headers" placeholder="请输入Headers，一行一个，冒号( : )分割name和value" autocomplete="off" class="layui-textarea"  lay-verify="required" style="height:250px"></textarea>`,
				area : '800px',
				btn : ['关闭','设置'],
				btn2 : function(){
					var headerStr = $("#headers").val();
					var headerArr = headerStr.split("\n");
					var length = $(".draggable").length;
					for (var i = 0; i < headerArr.length; i++) {
						var headerItem = headerArr[i];
						var index = headerItem.indexOf(":");
						if (index < 0) {
							layer.alert('header数据格式错误');
							return;
						} else {
							data.push({
								'header-name' : $.trim(headerItem.substring(0, index)),
								'header-value' : $.trim(headerItem.substring(index + 1))
							})
						}
					}
					layui.table.reload(tableId,{
						data : data
					});
					renderCodeMirror();
					serializeForm();
				}
			})
		}).on("click",".editor-form-node .parameter-batch",function () {
			var tableId = $(this).attr('for');
			var $table = $('#' + tableId);
			var cellId = $table.data('cell');
			var data = getCellData(cellId,$table.data('keys').split(","));
			layui.layer.open({
				type : 1,
				title : '请输入参数',
				content : `<textarea id="paramters" name="paramters" placeholder="请输入参数，一行一个，冒号( : )、等号（ = ）、空格（  ）或tab（ \t ）分割name和value" autocomplete="off" class="layui-textarea"  lay-verify="required" style="height:250px"></textarea>`,
				area : '800px',
				btn : ['关闭','设置'],
				btn2 : function(){
					var paramterStr = $("#paramters").val();
					var paramterArr = paramterStr.split("\n");
					var length = $(".draggable").length;
					for (var i = 0; i < paramterArr.length; i++) {
						var paramterItem = paramterArr[i];
						var index = -1;
						var indexArr = [];
						indexArr.push(paramterItem.indexOf(":"));
						indexArr.push(paramterItem.indexOf("="));
						indexArr.push(paramterItem.indexOf(" "));
						indexArr.push(paramterItem.indexOf("\t"));
						for (var j = 0; j < indexArr.length; j++) {
							if (indexArr[j] >= 0) {
								if (index < 0) {
									index = indexArr[j];
								}
								index = Math.min(index, indexArr[j]);
							}
						}
						if (index < 0) {
							layer.alert('参数数据格式错误');
							return;
						} else {
							data.push({
								'parameter-name' : $.trim(paramterItem.substring(0, index)),
								'parameter-value' : $.trim(paramterItem.substring(index + 1))
							})
						}
					}
					layui.table.reload(tableId,{
						data : data
					});
					renderCodeMirror();
					serializeForm();
				}
			})
		}).on("click",".editor-form-node .function-add",function(){
			var index = $(".draggable").length;
			$(this).parent().parent().before('<div id="function' + index + '" class="draggable" draggable="true" ondragstart="drag(event)" ondrop="drop(event)" ondragover="allowDrop(event)"><div class="layui-form-item layui-form-relative"><i class="layui-icon layui-icon-close function-remove"></i><label class="layui-form-label">执行函数</label><div class="layui-input-block array" codemirror="function" placeholder="执行函数"></div></div></div>');
			renderCodeMirror();
		}).on("click",".editor-form-node .cmd-add",function(){
			var index = $(".draggable").length;
			$(this).parent().parent().before('<div id="' + index + '" class="draggable" draggable="true" ondragstart="drag(event)" ondrop="drop(event)" ondragover="allowDrop(event)"><div class="layui-form-item layui-form-relative"><i class="layui-icon layui-icon-close cmd-remove"></i><label class="layui-form-label">执行命令</label><div class="layui-input-block array" codemirror="cmd" placeholder="执行命令"></div></div></div>');
			renderCodeMirror();
		});
		layui.form.on('select(bodyType)',function(e){
			var bodyType = $(e.elem).val();
			$(".form-body-raw,.form-body-form-data").hide();
			if(bodyType == 'raw'){
				$(".form-body-raw").show();
			}
			if(bodyType == 'form-data'){
				$(".form-body-form-data").show();
			}
			renderCodeMirror();
			serializeForm();
		});
        layui.form.on('select(targetCheck)', function (data) {
            var targetDiv = $(data.elem).attr('target-div');
            var targetValue = $(data.elem).attr('target-value');
            if (targetDiv != null) {
                if (data.elem.value == targetValue) {
                    $("." + targetDiv).show();
                } else {
                    $("." + targetDiv).hide();
                }
            }
        });

		layui.form.on('checkbox(targetCheck)', function (data) {
			var targetDiv = $(data.elem).attr('target-div');
			if (targetDiv != null) {
				if (data.elem.checked) {
					$("." + targetDiv).show();
				} else {
					$("." + targetDiv).hide();
				}
			}
		});
		layui.element.on('tab',function(){
			for(var key in codeMirrorInstances){
				codeMirrorInstances[key].refresh();
			}
		})
		layui.form.on('select',serializeForm);
		var id = getQueryString('id');
		if(id != null){
			$.ajax({
				url : 'spider/xml',
				async : false,
				data : {
					id : id
				},
				success : function(xml){
					editor.setXML(xml);
				}
			})
			//editor.importFromUrl('spider/xml?id=' +  id);
		}
		editor.onSelectedCell();
	}
	/**
	 * 加载各种图形
	 */
	function loadShapes(editor,container){
		//定义图形
		var shapes = [{
			name : 'start',
			title : '开始',
			image : '',
			hidden : true,
			defaultAdd : true
		},{
			name : 'request',
			image : '',
			title : '开始抓取',
			desc : '抓取静态HTML页面或者API接口，抓取结果存为resp变量中。<br/>支持方法参考命令提示。'
		},{
			name : 'variable',
			image : '',
			title : '定义变量',
			desc : '定义流程变量。<br/>定义变量有先后顺序，先定义变量后续可以使用，拖动可以交换变量顺序。'
		},{
			name : 'loop',
			image : '',
			title : '循环',
			desc : ''
		},{
			name : 'forkJoin',
			image : '',
			title : '执行结束',
			desc : ''
		},{
			name : 'comment',
			image : '',
			title : '注释',
			desc : '仅仅是注释,毫无作用'
		},{
			name : 'output',
			image : '',
			title : '输出',
			desc : '输出流程中的变量结果（仅测试下有用）'
		},{
			name : 'executeSql',
			image : '',
			title : '执行SQL',
			desc : '执行sql，需配置数据源，sql执行结果存于变量rs中。<br/>语句类型为：select，返回:List&lt;Map&lt;String,Object&gt;&gt;<br/>语句类型为：selectOne，返回:Map&lt;String,Object&gt;<br/>语句类型为：selectInt，返回:Integer<br/>语句类型为：insert、update、delete，返回:int，批量操作返回int数组<br/>sql中变量必须用 # # 包裹，如：#${title}#'
		},{
			name : 'function',
			image : '',
			title : '执行函数',
			desc : '单独执行函数方法，结果不保存为变量'
		},{
			name : 'process',
			image : '',
			title : '子流程',
			desc : '执行其他spiderFlow流程，父子流程变量共享'
		}];
		var addShape = function(shape){
			var image = new Image();
			image.src = shape.image;
			image.title = shape.title;
			image.id = shape.name;
			image.onclick = function (ev) {
				if(shape.desc){
					layer.tips("(" + shape.name + ")" + shape.title + "<hr/>" + shape.desc, '#' + shape.name,{
						tips: [1, '#3595CC'],
						area: ['auto', 'auto'],
						time: 4000
					});
				}
			}
			if(!shape.hidden){
				container.appendChild(image);
			}
			
			if(!shape.disabled){
				editor.addShape(shape.name,shape.title || 'Label',image,shape.defaultAdd);
			}
		}
		for(var i =0,len = shapes.length;i<len;i++){
			addShape(shapes[i]);
		}
		$.ajax({
			url : 'spider/shapes',
			type : 'post',
			dataType : 'json',
			async :false,
			success : function(shapeExts){
				for(var i =0,len = shapeExts.length;i<len;i++){
					var shape = shapeExts[i];
					addShape(shape);
					var image = new Image();
					image.src = shape.image;
					image.title = shape.title;
					editor.addShape(shape.name,shape.title || 'Label',image,false);
					resizeSlideBar();
				}
			}
		})
	}
});

/**
 * 绑定工具条点击事件
 */
function bindToolbarClickAction(editor){
	$(".xml-container textarea").bind('input propertychange',function(){
		editor.setXML($(this).val());
		editor.onSelectedCell();
	})
	$(".toolbar-container").on('click','.btn-delete',function(){
		editor.deleteSelectCells();
	}).on("click",".btn-selectAll",function(){
		editor.execute('selectAll');
	}).on('click',".btn-undo",function(){
		editor.execute('undo');
	}).on('click',".btn-redo",function(){
		editor.execute('redo');
	}).on('click',".btn-cut",function(){
		editor.execute('cut');
	}).on('click',".btn-copy",function(){
		editor.execute('copy');
	}).on('click',".btn-paste",function(){
		editor.execute('paste');
	}).on('click',".btn-console-xml",function(){
		console.log(editor.getXML());
	}).on('click',".btn-edit-xml",function(){
		$(".editor-container").hide();
		$(".xml-container textarea").val(editor.getXML());
		$(".xml-container").show();
		$(this).removeClass('btn-edit-xml').addClass('btn-graphical-xml');
	}).on('click',".btn-graphical-xml",function(){
		$(".editor-container").show();
		$(".xml-container").hide();
		$(this).removeClass('btn-graphical-xml').addClass('btn-edit-xml');
//		editor.setXML($(".xml-container textarea").val());
//		editor.onSelectedCell();
	}).on('click','.btn-stop:not(.disabled)',function () {
		socket.send(JSON.stringify({
			eventType : 'stop'
		}));
	}).on('click','.btn-resume:not(.disabled)',function () {
		$(this).addClass('disabled')
		$(".spiderflow-debug-tooltip").remove();
		socket.send(JSON.stringify({
			eventType : 'resume'
		}));
	}).on('click','.btn-test',function(){
		runSpider(false);
	}).on('click','.btn-debug',function(){
		runSpider(true);
	}).on('click',".btn-return",function(){
		parent.openTab('爬虫列表','welcome','spiderList.html')
	}).on('click','.btn-save',function(){
		Save();
	}).on('click','.btn-dock-right',function(){
		$('.main-container').addClass('right');
		$('.main-container .properties-container').width('40%');
		$('.main-container .resize-container').attr('style','top:0px;left:auto;');
		layui.table.resize('spider-variable');
		var resize = $('.resize-container')[0]
		resize.onmousedown = function(e){
			var startX = e.clientX;
			resize.left = resize.offsetLeft;
			var box = $("body")[0];
			document.onmousemove = function(e){
				layui.table.resize('spider-variable');
				var endX = e.clientX;
				var moveLen = resize.left + (endX - startX);
				var maxT = box.clientWidth - resize.offsetWidth;
				if(moveLen<150) moveLen = 150;
				if(moveLen>maxT-150) moveLen = maxT-150;
				if(box.clientWidth - moveLen < 400 || box.clientWidth - moveLen > 800){
				return;
				}
				resize.style.left = moveLen + 'px';
				$(".editor-container").css('right',($('body').width() - moveLen) + 'px')
				$(".properties-container").width(box.clientWidth - moveLen - 5);
				$(".xml-container").width($(".main-container").width() - $(".properties-container").width() - $(".sidebar-container").width() + 8);
			}
			document.onmouseup = function(evt){
				document.onmousemove = null;
				document.onmouseup = null;
				resize.releaseCapture && resize.releaseCapture();
			}
			resize.setCapture && resize.setCapture();
			return false;
		}
	}).on('click','.btn-dock-bottom',function(){
		resizeSlideBar();
		$('.main-container').removeClass('right');
		$('.properties-container').height(200).width('100%');
		$('.sidebar-container').css('bottom','200px');
		$('.editor-container').css('bottom','200px');
		$('.main-container .resize-container').attr('style','left:0px;top:auto;bottom:190px');
		var resize = $('.resize-container')[0]
		resize.onmousedown = function(e){
			var startY = e.clientY;
			resize.top = resize.offsetTop;
			var box = $("body")[0];
			var maxT = box.clientHeight;
			document.onmousemove = function(e){
			  var moveLen = e.clientY;
			  if(moveLen<250) moveLen = 250;
			  if(moveLen>maxT-150) moveLen = maxT-150;
			  resize.style.top = moveLen + 'px';
			  resizeSlideBar();
			  $(".editor-container,.sidebar-container,.xml-container").css('bottom',($('body').height() - moveLen) + 'px');
			  $(".properties-container").height(box.clientHeight - moveLen - 5);
			}
			document.onmouseup = function(evt){
				document.onmousemove = null;
				document.onmouseup = null;
				resize.releaseCapture && resize.releaseCapture();
			}
			resize.setCapture && resize.setCapture();
			return false;
		}
	})
	$('.btn-dock-bottom').click();
}
function runSpider(debug){
	validXML(function(){
		$(".btn-debug,.btn-test,.btn-resume").addClass('disabled');
		$(".btn-stop").removeClass('disabled');
		var LogViewer;
		var tableMap = {};
		var first = true;
		var filterText = '';
		var testWindowIndex = layui.layer.open({
			id : 'test-window',
			type : 1,
			skin : 'layer-test',
			content : '<div class="test-window-container"><div class="output-container"><div class="layui-tab layui-tab-fixed layui-tab-brief"><ul class="layui-tab-title"></ul><div class="layui-tab-content"></div></div></div><canvas class="log-container" width="677" height="100"></canvas></div>',
			area : ["680px","400px"],
			shade : 0,
			offset : 'rt',
			maxmin :true,
			maxWidth : 700,
			maxHeight : 400,
			title : '测试窗口',
			btn : ['关闭','显示/隐藏输出','显示/隐藏日志','停止'],
			btn2 : function(){
				var $output = $(".test-window-container .output-container");
				var $log = $(".test-window-container .log-container");
				if($output.is(":hidden")){
					$output.show();
					$output.find("canvas").each(function(){
						if($log.is(":hidden")){
							this.height = 290;
						}else{
							this.height = 200;
						}
					})
					$log.attr('height',100)
					LogViewer.resize();
					for(var tableId in tableMap){
						tableMap[tableId].instance.resize();
					}
				}else{
					$output.hide();
					$log.attr('height',320);
					LogViewer.resize();
					for(var tableId in tableMap){
						tableMap[tableId].instance.resize();
					}
				}
				return false;
			},
			btn3 : function(){
				var $output = $(".test-window-container .output-container");
				var $log = $(".test-window-container .log-container");
				if($log.is(":hidden")){
					$log.show();
					$log.attr('height',$output.is(":hidden") ? 320 : 100)
					$output.find("canvas").each(function(){
						this.height = 200;
					});
					LogViewer.resize();
					for(var tableId in tableMap){
						tableMap[tableId].instance.resize();
					}
				}else{
					$log.hide();
					$output.find("canvas").each(function(){
						this.height = 320;
					});
					LogViewer.resize();
					for(var tableId in tableMap){
						tableMap[tableId].instance.resize();
					}
				}
				return false;
			},
			btn4 : function(){
				var $btn = $("#layui-layer" + testWindowIndex).find('.layui-layer-btn3');
				if($btn.html() == '停止'){
					socket.send(JSON.stringify({
						eventType : 'stop'
					}));
				}else{
					$(".btn-debug,.btn-test,.btn-resume").addClass('disabled');
					$(".btn-stop").removeClass('disabled');
					socket.send(JSON.stringify({
						eventType : debug ? 'debug' : 'test',
						message : editor.getXML()
					}));
					$btn.html('停止');
				}
				return false;
			},
			end : function(){
				if(socket){
					socket.close();
					$(".spiderflow-debug-tooltip").remove();
					$(".btn-stop,.btn-resume").addClass('disabled');
					$(".btn-test,.btn-debug").removeClass('disabled')
				}
				if(LogViewer){
					LogViewer.destory();
				}
				for(var tableId in tableMap){
					tableMap[tableId].instance.destory();
				}
			},
			success : function(layero,index){
				var logElement = $(".test-window-container .log-container")[0];
				var colors = {
					'array' : '#2a00ff',
					'object' : '#2a00ff',
					'boolean' : '#600100',
					'number' : '#000E59'
				}
				LogViewer = new CanvasViewer({
					element : logElement,
					onClick : function(e){
						onCanvasViewerClick(e,'日志');
					}
				});
				$(layero).find(".layui-layer-btn")
					.append('<div class="layui-inline"><input type="text" class="layui-input" placeholder="输入关键字过滤日志"/></div>')
					.on("keyup","input",function(){
						LogViewer.filter(this.value);
					});
				socket = createWebSocket({
					onopen : function(){
						socket.send(JSON.stringify({
							eventType : debug ? 'debug' : 'test',
							message : editor.getXML()
						}));
					},
					onmessage : function(e){
						var event = JSON.parse(e.data);
						var eventType = event.eventType;
						var message = event.message;
						if(eventType == 'finish'){
							$(".spiderflow-debug-tooltip").remove();
							$("#layui-layer" + testWindowIndex).find('.layui-layer-btn3').html('重新开始');
							$(".btn-stop,.btn-resume").addClass('disabled');
							$(".btn-test,.btn-debug").removeClass('disabled')
						}else if(eventType == 'output'){
							var tableId = 'output-' + message.nodeId;
							var $table = $('#' + tableId);
							if($table.length == 0){
								tableMap[tableId] = {
									index : 0
								};
								var $tab = $(".test-window-container .output-container .layui-tab")
								var outputTitle = '输出-'+tableId;
								var cell = editor.getModel().cells[message.nodeId];
								if(cell){
									outputTitle = cell.value;
								}
								if(first){
									$tab.find(".layui-tab-title").append('<li  class="layui-this">' + outputTitle + '</li>');
									$tab.find(".layui-tab-content").append('<div class="layui-tab-item layui-show" data-output="'+tableId+'"></div>');
									first = false;
								}else{
									$tab.find(".layui-tab-title").append('<li>' + outputTitle + '</li>');
									$tab.find(".layui-tab-content").append('<div class="layui-tab-item" data-output="'+tableId+'"></div>');
								}
								$table = $('<canvas width="677" height="200"/>').appendTo($(".test-window-container .output-container .layui-tab-item[data-output="+tableId+"]"));
								$table.attr('id',tableId);
								tableMap[tableId].instance = new CanvasViewer({
									element : document.getElementById(tableId),
									grid : true,
									header : true,
									style : {
										font : 'bold 13px Consolas'
									},
									onClick : function(e){
										onCanvasViewerClick(e,'表格');
									}
								})
								var cols = [];
								var texts = [new CanvasText({
									text : '序号',
									maxWidth : 100
								})];
								for(var i =0,len = message.outputNames.length;i<len;i++){
									texts.push(new CanvasText({
										text : message.outputNames[i],
										maxWidth : 200,
										click : true
									}));
								}
								tableMap[tableId].instance.append(texts);
							}
							var texts = [new CanvasText({
								text : ++tableMap[tableId].index,
								maxWidth : 200,
								click : true
							})];
							for(var i =0,len = message.outputNames.length;i<len;i++){
								var displayText = message.values[i];
								var variableType = 'string';
								if(Array.isArray(displayText)){
									variableType = 'array';
									displayText = JSON.stringify(displayText);
								}else{
									variableType = typeof displayText;
									if(variableType == 'object'){
										displayText = JSON.stringify(displayText);
									}
								}
								texts.push(new CanvasText({
									text : displayText,
									maxWidth : 200,
									color : colors[variableType] || 'black',
									click : true
								}));
							}
							tableMap[tableId].instance.append(texts);
							tableMap[tableId].instance.scrollTo(-1);
						}else if(eventType == 'log'){
							var texts = [];
							var defaultColor = message.level == 'error' ? 'red' : '';
							texts.push(new CanvasText({
								text : message.level,
								color : defaultColor
							}));
							texts.push(new CanvasText({
								text : event.timestamp,
								color : defaultColor
							}));
							var temp = message.message.split("{}");
							message.variables = message.variables || [];
							for(var i=0,len=temp.length;i<len;i++){
								if(temp[i]!=''){
									texts.push(new CanvasText({
										text : temp[i],
										color : defaultColor
									}))
								}
								var object = message.variables[i];
								if(object != undefined){
									var variableType = '';
									var displayText = object;
									if(Array.isArray(object)){
										variableType = 'array';
										displayText = JSON.stringify(displayText);
									}else{
										variableType = typeof object;
										if(variableType == 'object'){
											displayText = JSON.stringify(displayText);
										}
									}
									texts.push(new CanvasText({
										text : displayText,
										maxWidth : 330,
										color : colors[variableType] || '#025900',
										click : true
									}))
								}
							}
							LogViewer.append(texts);
							LogViewer.scrollTo(-1);
						}else if(eventType == 'debug'){
							$(".btn-resume").removeClass('disabled');
							var type = message.event;
							editor.selectCell(editor.graph.model.cells[message.nodeId]);
							var selector;
							if(type == 'request-parameter'){
								$('.layui-tab-title li:eq(1)').click();
							}
							if(type == 'request-cookie'){
								$('.layui-tab-title li:eq(2)').click();
							}
							if(type == 'request-header'){
								$('.layui-tab-title li:eq(3)').click();
							}
							if(type == 'request-body'){
								$('.layui-tab-title li:eq(4)').click();
							}
							if(type == 'common' || type == 'request-parameter' || type == 'request-header' || type == 'request-cookie'){
								selector = '.layui-table-cell input[value='+message.key+']';
							}
							if($(selector).length == 0){
								selector = '.properties-container input[name='+message.key+']';
							}
							if($(selector).length == 0){
								selector = '.properties-container [codemirror='+message.key+']';
							}
							var o1 = $(selector).offset();
							var $parent = $(".properties-container");
							var o2 = $parent.offset();
							if(o1.top > o2.top + $parent.height()){
								$parent[0].scrollTop = o1.top - o2.top;
							}
							var msg = message.value;
							var isJson = Array.isArray(msg) || typeof msg == 'object';
							if(!isJson){
								var temp = document.createElement("div");
								(temp.textContent != null) ? (temp.textContent = msg) : (temp.innerText = msg);
								msg = temp.innerHTML;
								temp = null;
							}
							var content = '<div class="message-content" style="padding:10px;'+(isJson ? '':'font-weight: bold;font-family:Consolas;font-size:12px;')+'">'+(isJson ? '' : msg.replace(/\n/g,'<br>')).replace(/ /g,'&nbsp;').replace(/\t/g,'&nbsp;&nbsp;&nbsp;&nbsp;')+'</div>';
							var tooltip = bindTooltip(content,selector);
							if(isJson){
								var $dom = $(tooltip.dom).find(".message-content");
								jsonTree.create(msg,$dom[0]);
							}
						}
					}
				});
			}
		})
	});
}
function bindTooltip(content,selector){
	var dom = document.createElement('div');
	var $target = $(selector);
	var offset = $target.offset();
	dom.className = 'spiderflow-debug-tooltip';
	dom.style.bottom = ($("body").height() - offset.top) + 'px';
	dom.style.left = (offset.left + $target.width() / 2) + 'px';
	dom.innerHTML = '<div class="content">' + content + '</div>';
	document.body.appendChild(dom);
	$(selector).offset();
	return {
		dom : dom,
		close : function(){
			document.body.removeChild(dom);
		}
	}

}
//最近点击打开的弹窗
var index;
function onCanvasViewerClick(e,source){
	var msg = e.text;
	var json;
	try{
		json = JSON.parse(msg);
		if(!(Array.isArray(json) || typeof json == 'object')){
			json = null;
		}
	}catch(e){
		
	}
	if(!json){
		var temp = document.createElement("div");
		(temp.textContent != null) ? (temp.textContent = msg) : (temp.innerText = msg);
		msg = temp.innerHTML;
		temp = null;
	}
	layer.close(index);
	index = layer.open({
	  type : 1,
	  title : source +'内容',
	  content: '<div class="message-content" style="padding:10px;'+(json ? '':'font-weight: bold;font-family:Consolas;font-size:12px;')+'">'+(json ? '' : msg.replace(/\n/g,'<br>')).replace(/ /g,'&nbsp;').replace(/\t/g,'&nbsp;&nbsp;&nbsp;&nbsp;')+'</div>',
	  shade : 0,
	  area : json ? ['700px','500px'] : 'auto',
	  maxmin : true,
	  maxWidth : (json ? undefined : 700),
	  maxHeight : (json ? undefined : 400),
	  success : function(dom,index){
		 var $dom = $(dom).find(".message-content");
		 if(json){
			 jsonTree.create(json,$dom[0]);
		 }
	  }
	}); 
}
function createWebSocket(options){
	options = options || {};
	var socket;
	if(location.host === 'demo.spiderflow.org'){
		socket = new WebSocket(options.url || 'ws://49.233.182.130:8088/ws');
	}else{
		socket = new WebSocket(options.url || (location.origin.replace("http",'ws') + '/ws'));
	}
	socket.onopen = options.onopen;
	socket.onmessage = options.onmessage;
	socket.onerror = options.onerror || function(){
		layer.layer.msg('WebSocket错误');
	}
	return socket;
}

var flowId;
function Save(){
	validXML(function(){
		$.ajax({
			url : 'spider/save',
			type : 'post',
			data : {
				id : getQueryString('id') || flowId,
				xml : editor.getXML(),
				name : editor.graph.getModel().getRoot().data.get('spiderName') || '未定义名称',
			},
			success : function(id) {
				flowId = id;
				layui.layer.msg('保存成功', {
					time : 800
				}, function() {
					// location.href = "spiderList.html";
				})
			}
		})
	});
}

function allowDrop(ev){
	ev.preventDefault();
}

function drag(ev){
	ev.dataTransfer.setData("moverTarget", ev.target.id);
}

function drop(ev){
	var moverTargetId = ev.dataTransfer.getData("moverTarget");
	$(ev.target).parents(".draggable").before($("#" + moverTargetId));
	ev.preventDefault();
	serializeForm();
}